package wiModel;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import wiBase.WiException;

public class WiModelTest extends DefaultHandler {
	@SuppressWarnings("rawtypes")
	private Hashtable tags;

	public static void main(String[] args) {
//		WiModelTest test=new WiModelTest();
//		test.doParse();
		
		WiModelManager mng=new WiModelManager();
		mng.setTraceFile("res/trace/wissim-trace.xml");
	try {
	    mng.parse();
	} catch (WiException ex) {
	}
		
		System.out.println("Nodes:"+mng.getListNodes().size());
		System.out.println("Events:"+mng.getListEvents().size());
		System.out.println("Packets:"+mng.getListPackets().size());
		
		System.out.println(mng.getPacket(0).toString());
	}
	public void doParse(){
		// the SAXParserFactory class that creates the parser instance used.
		SAXParserFactory spf = SAXParserFactory.newInstance();
		spf.setNamespaceAware(true);
		try {
			/* Throws a ParserConfigurationException 
			 *  if it cannot produce a parser that 
			 *  matches the specified configuration of options.*/
			SAXParser saxParser = spf.newSAXParser();
			
			/* The SAXParser class, which is what the factory 
			 *  returns for parsing.*/
			XMLReader xmlReader = saxParser.getXMLReader();
			
			/* Set listener for parse SAX */
			xmlReader.setContentHandler(new WiModelTest());
			xmlReader.parse(convertToFileURL("./res/trace/trace.xml"));
			/* It is safer to implement some error handling. */
			xmlReader.setErrorHandler(new MyErrorHandler(System.err));
		} catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}
	}
	String currentContent="";
	@Override
	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
		// TODO Auto-generated method stub
		StringBuilder builder=new StringBuilder();
		builder.append(new String(arg0, arg1, arg2));
		currentContent=builder.toString().trim();
//		System.out.println(builder.toString().trim());
		super.characters(arg0, arg1, arg2);
	}
	/* The major event-handling methods are: 
	 * 	startDocument, 
	 * 	endDocument, 
	 * 	startElement, 
	 *	endElement.*/
	
	/* Defines what the application does when the parser 
	 *  encounters the start points of the document being parsed.*/
	@SuppressWarnings("rawtypes")
	public void startDocument() throws SAXException {
		tags = new Hashtable();
	}
	/* Defines what the application does when the parser 
	 *  encounters the end points of the document being parsed.*/
	@SuppressWarnings("rawtypes")
	public void endDocument() throws SAXException {
		Enumeration e = tags.keys();
		while (e.hasMoreElements()) {
			String tag = (String) e.nextElement();
			int count = ((Integer) tags.get(tag)).intValue();
			System.out.println("Local Name \"" + tag + "\" occurs " + count
					+ " times");
		}
	}
	/* When a start tag is encountered.
	 * Any attributes it defines are also passed in an Attributes list. 
	 * Characters found within the element are passed as an array of characters.*/
	@SuppressWarnings("unused")
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes atts) throws SAXException {
		/* Processes the element tags, 
		 * including:
		 * 	the namespace universal resource identifier (URI), 
		 *  the local name and 
		 *  the qualified name of that element,
		 *  any attributes defined in the start tag.*/
		String key = localName;
		System.out.println(localName+"/");
	}
	/* When a end tag is encountered */
	@Override
	public void endElement(String namespaceURI, String localName, String qName)
			throws SAXException {

		System.out.println(currentContent);
		System.out.println("/"+localName);
		super.endElement(namespaceURI, localName, qName);
	}
	

	private static String convertToFileURL(String filename) {
		String path = new File(filename).getAbsolutePath();
		if (File.separatorChar != '/') {
			path = path.replace(File.separatorChar, '/');
		}

		if (!path.startsWith("/")) {
			path = "/" + path;
		}
		return "file:" + path;
	}

	private static class MyErrorHandler implements ErrorHandler {
		private PrintStream out;

		MyErrorHandler(PrintStream out) {
			this.out = out;
		}

		private String getParseExceptionInfo(SAXParseException spe) {
			String systemId = spe.getSystemId();

			if (systemId == null) {
				systemId = "null";
			}

			String info = "URI=" + systemId + " Line=" + spe.getLineNumber()
					+ ": " + spe.getMessage();

			return info;
		}

		public void warning(SAXParseException spe) throws SAXException {
			out.println("Warning: " + getParseExceptionInfo(spe));
		}
		/* nonFatal error! */
		public void error(SAXParseException spe) throws SAXException {
			String message = "Error: " + getParseExceptionInfo(spe);
			throw new SAXException(message);
		}
		/* When a fatal error occurs, the parser cannot continue. */
		public void fatalError(SAXParseException spe) throws SAXException {
			String message = "Fatal Error: " + getParseExceptionInfo(spe);
			throw new SAXException(message);
		}
	}
}
